package com.neuronrobotics.replicator.gui.preview.android;

import android.opengl.GLES20;

public class ShaderUtility {
	
	public static final String perVertex_VertexShaderCode =

	"uniform mat4 uPMatrix;" +
	"uniform mat4 uVMatrix;" + 
			"uniform mat4 uMMatrix;" +

			"uniform vec3 uLightPos;" +

			"attribute vec4 aPosition;" + 
			"attribute vec4 aColor;"
			+ "attribute vec3 aNormal;" +

			"varying vec4 vColor;" +

			"void main() {"
			+
			// Transform the vertex into eye space.
			"vec3 modelViewVertex = vec3(uVMatrix * uMMatrix * aPosition);"
			+
			// Transform the normal's orientation into eye space.
			"vec3 modelViewNormal = vec3(uVMatrix * uMMatrix * vec4(aNormal, 0.0));"
			+
			// Will be used for attenuation.
			"float distance = length(uLightPos - modelViewVertex);" +
			// Get a lighting direction vector from the light to the vertex.
			"vec3 lightVector = normalize(uLightPos - modelViewVertex);" +
			// Calculate the dot product of the light vector and vertex normal.
			// If the normal and light vector are
			// pointing in the same direction then it will get max illumination.
			"float diffuse = max(dot(modelViewNormal, lightVector), 0.1);" +
			// Attenuate the light based on distance.
			"diffuse = diffuse * (40.0 / (1.0 + (.25*(distance*distance))));" +
			// Multiply the color by the illumination level. It will be
			// interpolated across the triangle.
			// "diffuse = 1.0f;"+
			"vColor = aColor * diffuse;" +
			// the matrix must be included as a modifier of gl_Position
			"gl_Position = uPMatrix * uVMatrix * uMMatrix * aPosition;" + "}";

	public static final String perVertex_fragmentShaderCode = "precision mediump float;"
			+ "varying vec4 vColor;"

			+ "void main() {" + "  gl_FragColor = vColor;" + "}";

	public static final String perPixel_VertexShaderCode = "uniform mat4 uPMatrix;"
			+ "uniform mat4 uVMatrix;" + "uniform mat4 uMMatrix;" +

			"attribute vec4 aPosition;" + // Per-vertex position information we
											// will pass in.
			"attribute vec4 aColor;" + // Per-vertex color information we will
										// pass in.
			"attribute vec3 aNormal;" + // Per-vertex normal information we will
										// pass in.

			"varying vec3 vPosition;" + // This will be passed into the fragment
										// shader.
			"varying vec4 vColor;" + // This will be passed into the fragment
										// shader.
			"varying vec3 vNormal;" + // This will be passed into the fragment
										// shader.

			// The entry point for our vertex shader.
			"void main()" + "{" +
			// Transform the vertex into eye space.
			"vPosition = vec3(uVMatrix * uMMatrix * aPosition);" +

			// Pass through the color.
			"vColor = aColor;" +

			// Transform the normal's orientation into eye space.
			"vNormal = vec3(uVMatrix * uMMatrix * vec4(aNormal, 0.0));" +

			// gl_Position is a special variable used to store the final
			// position.
			// Multiply the vertex by the matrix to get the final point in
			// normalized screen coordinates.
			"gl_Position = uPMatrix * uVMatrix * uMMatrix * aPosition;" + "}";

	public static final String perPixel_FragmentShaderCode = "precision mediump float;"
			+ // Set the default precision to medium. We don't need as high of a
				// precision in the fragment shader.
			"uniform vec3 uLightPos;"
			+ // The position of the light in eye space.

			"varying vec3 vPosition;"
			+ // Interpolated position for this fragment.
			"varying vec4 vColor;"
			+ // This is the color from the vertex shader interpolated across
				// the
			// triangle per fragment.
			"varying vec3 vNormal;"
			+ // Interpolated normal for this fragment.

			// The entry point for our fragment shader.
			"void main()"
			+ "{"
			+
			// Will be used for attenuation.
			"float distance = length(uLightPos - vPosition);"
			+

			// Get a lighting direction vector from the light to the vertex.
			"vec3 lightVector = normalize(uLightPos - vPosition);"
			+

			// Calculate the dot product of the light vector and vertex normal.
			// If the normal and light vector are
			// pointing in the same direction then it will get max illumination.
			"float diffuse = max(dot(vNormal, lightVector), 0.1);"
			+

			// Add attenuation.
			"diffuse = diffuse * (5000.0 / (1.0 + (0.25 * distance * distance)));"
			+
			// "vColor = vec4(normalize(vPosition),1.0);"+
			// Multiply the color by the diffuse illumination level to get final
			// output color.
			"gl_FragColor = vColor * diffuse;" + "}";
	
	public static final String perPixel_VertexShaderCode_OneColor = "uniform mat4 uPMatrix;"
			+ "uniform mat4 uVMatrix;" + "uniform mat4 uMMatrix;" +

			"attribute vec4 aPosition;" + // Per-vertex position information we
											// will pass in.
			"uniform vec4 aColor;" + // Per-vertex color information we will
										// pass in.
													
			"attribute vec3 aNormal;" + // Per-vertex normal information we will
										// pass in.

			"varying vec3 vPosition;" + // This will be passed into the fragment
										// shader.
			"varying vec4 vColor;" + // This will be passed into the fragment
										// shader.
			"varying vec3 vNormal;" + // This will be passed into the fragment
										// shader.

			// The entry point for our vertex shader.
			"void main()" + "{" +
			// Transform the vertex into eye space.
			"vPosition = vec3(uVMatrix * uMMatrix * aPosition);" +

			// Pass through the color.
			"vColor = aColor;" +

			// Transform the normal's orientation into eye space.
			"vNormal = vec3(uVMatrix * uMMatrix * vec4(aNormal, 0.0));" +

			// gl_Position is a special variable used to store the final
			// position.
			// Multiply the vertex by the matrix to get the final point in
			// normalized screen coordinates.
			"gl_Position = uPMatrix * uVMatrix * uMMatrix * aPosition;" + "}";

	public static final String perPixel_FragmentShaderCode_OneColor = "precision mediump float;"
			+ // Set the default precision to medium. We don't need as high of a
				// precision in the fragment shader.
			"uniform vec3 uLightPos;"
			+ // The position of the light in eye space.
						
			"uniform int lightsOn;"+
			
			"varying vec3 vPosition;"
			+ // Interpolated position for this fragment.
			"varying vec4 vColor;"
			+ // This is the color from the vertex shader interpolated across
				// the
			// triangle per fragment.
			"varying vec3 vNormal;"
			+ // Interpolated normal for this fragment.

			// The entry point for our fragment shader.
			"void main()"
			+ "{"
			+
			// Will be used for attenuation.
			"float distance = length(uLightPos - vPosition);"
			+

			// Get a lighting direction vector from the light to the vertex.
			"vec3 lightVector = normalize(uLightPos - vPosition);"
			+

			// Calculate the dot product of the light vector and vertex normal.
			// If the normal and light vector are
			// pointing in the same direction then it will get max illumination.
			"float diffuse = max(dot(vNormal, lightVector), 0.1);"
			+

			// Add attenuation.
			"diffuse = diffuse * (5000.0 / (1.0 + (0.25 * distance * distance)));"
			+
			// "vColor = vec4(normalize(vPosition),1.0);"+
			// Multiply the color by the diffuse illumination level to get final
			// output color.
			"if(lightsOn!=0)"+
			"gl_FragColor = vColor * diffuse;" 
			+"else gl_FragColor = vColor;"
			+ "}";

	public static int loadShader(int type, String shaderCode){
		
	        // create a vertex shader type (GLES20.GL_VERTEX_SHADER)
	        // or a fragment shader type (GLES20.GL_FRAGMENT_SHADER)
	        int shader = GLES20.glCreateShader(type);

	        // add the source code to the shader and compile it
	        GLES20.glShaderSource(shader, shaderCode);
	        GLES20.glCompileShader(shader);

	        return shader;
	    }
	
}
